#include "timer.h"
#include "keyboard.h"
#include "uart.h"
#include "lcd.h"

const char keys[] =
{
    '1', '4', '7', '\n',
    '2', '5', '8', '0',
    '3', '6', '9', '\b',
    'A', 'B', 'C', 'D'
};

const char multi_keys[][4] =
{
    {               }, { 'G', 'H', 'I' }, { 'P', 'Q', 'R', 'S' }, {},
    { 'A', 'B', 'C' }, { 'J', 'K', 'L' }, { 'T', 'U', 'V'      }, { ' ' },
    { 'D', 'E', 'F' }, { 'M', 'N', 'O' }, { 'W', 'X', 'Y', 'Z' }, {},
    {}, {}, {}, {}
};

char buf[17];
int buf_len = 0;

void buf_push(char c)
{
    if (buf_len < 16)
    {
        lcd_print_char(2 + buf_len * 8, 114, c, 0, -1);
        buf[buf_len++] = c;
    }
}

void buf_pop(void)
{
    if (buf_len > 0)
    {
        buf_len--;
        lcd_fill_rect(2 + buf_len * 8, 114, 8, 16, 0);
    }
}

void buf_set(char c)
{
    if (buf_len > 0)
    {
        lcd_print_char(2 + (buf_len - 1) * 8, 114, c, 0, -1);
        buf[buf_len - 1] = c;
    }
}

void buf_clear(void)
{
    if (buf_len > 0)
    {
        lcd_fill_rect(2, 114, buf_len * 8, 16, 0);
        buf_len = 0;
    }
}

void on_tick(void)
{
    // uart_send_char('*');
}

void main(void)
{
    keyboard_init();

    uart_init();

    lcd_init();

    timer_on_tick(on_tick);
    timer_init();

    lcd_fill_rect(0, 0, 132, 132, 0);
    lcd_print_char(20, 20, 'H', 0, LCD_COLOR(0x00ffff));
    lcd_print_char(28, 20, 'e', 0, LCD_COLOR(0xff00ff));
    lcd_print_char(36, 20, 'l', 0, LCD_COLOR(0xffff00));
    lcd_print_char(44, 20, 'l', 0, LCD_COLOR(0xff0000));
    lcd_print_char(52, 20, 'o', 0, LCD_COLOR(0x00ff00));
    lcd_print_char(60, 20, '!', 0, LCD_COLOR(0x0000ff));
    for (int i = 0; i < 16; i++)
    {
        lcd_print_char_wide(16 * (i % 8), 60 + 16 * (i / 8), i, 0, -1);
    }

    int last_key = 0;
    while (1)
    {
        int k = keyboard_get_key();
        if (k >= 12)
        {
            char mk = multi_keys[last_key][k - 12];
            if (mk) buf_set(mk);
        }
        else if (k == 3)
        {
            buf[buf_len] = 0;
            uart_send_line(buf);
            buf_clear();
        }
        else if (k == 11)
        {
            buf_pop();
        }
        else
        {
            buf_push(keys[k]);
        }
        for (int i = 0; i < 4; i++)
        {
            char mk = multi_keys[k][i];
            if (mk) lcd_print_char(2 + i * 8, 98, mk, 0, -1);
            else lcd_fill_rect(2 + i * 8, 98, 8, 16, 0);
        }
        last_key = k;
    }
}
